import json
import time
from datetime import datetime, timezone, timedelta
from flask import request, jsonify, current_app, url_for, Blueprint
from flasgger import swag_from
from app import db
from app.models.order import Order
from app.models.payment import Payment
from app.api.v1 import api_v1
from app.utils.decorators import login_required, admin_required
from app.utils.wechat_pay import WechatPayAPI
from app.utils.order import generate_payment_no, generate_checkin_code
from app.utils.response import success_response, error_response
from app.api.v1.docs.payment_docs import (
    CREATE_PAYMENT_DOC, PAYMENT_NOTIFY_DOC, QUERY_PAYMENT_DOC,
    MANUAL_PAYMENT_NOTIFY_DOC
)




@api_v1.route('/payments/create', methods=['POST'])
@swag_from(CREATE_PAYMENT_DOC)
@login_required
def create_payment():
    """创建支付订单"""
    data = request.get_json()
    if not data:
        return jsonify({'code': 400, 'message': '缺少请求数据'}), 400
    
    # 验证必要参数
    required_fields = ['orderId', 'userId']
    for field in required_fields:
        if field not in data:
            return jsonify({'code': 400, 'message': f'缺少必要参数: {field}'}), 400
    
    order_id = data.get('orderId')
    user_id = data.get('userId')
    
    # 查询订单
    order = Order.query.get_or_404(order_id)
    
    # 验证订单所属用户
    if str(order.user_id) != str(user_id):
        return jsonify({'code': 403, 'message': '无权操作该订单'}), 403
    
    # 验证订单状态
    if order.status != 0:  # 只有未支付的订单可以创建支付
        return jsonify({'code': 400, 'message': '该订单状态不允许支付'}), 400
    
    try:
        # 生成支付流水号
        payment_no = generate_payment_no()
        
        # 创建支付记录
        payment = Payment(
            order_id=order.id,
            payment_no=payment_no,
            amount=order.amount,
            payment_method='wechat',
            status=0  # 未支付
        )
        db.session.add(payment)
        db.session.commit()
        
        # 调用微信支付API
        wechat_pay = WechatPayAPI()
        
        # 构建支付参数
        params = {
            'description': f'体育场馆预约-{order.venue.name}',
            'out_trade_no': payment_no,
            'amount': {
                'total': int(float(order.amount) * 100),  # 微信支付金额单位为分
                'currency': 'CNY'
            },
            'notify_url': current_app.config['WECHAT_PAY_NOTIFY_URL'],
            'payer': {
                'openid': order.user.openid
            }
        }
        
        # 调用微信支付统一下单接口
        result = wechat_pay.create_jsapi_payment(params)
        
        if result and 'prepay_id' in result:
            # 返回支付参数给前端
            return jsonify({
                'code': 200,
                'message': '支付订单创建成功',
                'data': {
                    'paymentId': payment.id,
                    'paymentNo': payment.payment_no,
                    'amount': float(payment.amount),
                    'payParams': result
                }
            })
        else:
            # 支付创建失败
            db.session.delete(payment)
            db.session.commit()
            return jsonify({'code': 500, 'message': '微信支付创建失败'}), 500
        
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"创建支付异常: {str(e)}")
        return jsonify({'code': 500, 'message': '服务器错误'}), 500


@api_v1.route('/payments/notify', methods=['POST'])
@swag_from(PAYMENT_NOTIFY_DOC)
def payment_notify():
    """微信支付回调通知"""
    try:
        # 获取微信支付回调数据
        wechat_pay = WechatPayAPI()
        
        # 验证签名并解密数据
        data = wechat_pay.parse_payment_notification(request)
        
        if not data:
            current_app.logger.error("支付回调数据解析失败")
            return jsonify({'code': 'FAIL', 'message': '回调数据解析失败'}), 400
        
        # 处理支付结果
        resource = data.get('resource', {})
        result = resource.get('ciphertext', {})
        
        # 解析支付结果
        if isinstance(result, str):
            try:
                result = json.loads(result)
            except:
                current_app.logger.error("支付结果解析失败")
                return jsonify({'code': 'FAIL', 'message': '支付结果解析失败'}), 400
        
        # 获取商户订单号
        payment_no = result.get('out_trade_no')
        transaction_id = result.get('transaction_id')
        trade_state = result.get('trade_state')
        
        if not payment_no or not transaction_id or not trade_state:
            current_app.logger.error("支付回调缺少必要参数")
            return jsonify({'code': 'FAIL', 'message': '缺少必要参数'}), 400
        
        # 查询支付记录
        payment = Payment.query.filter_by(payment_no=payment_no).first()
        if not payment:
            current_app.logger.error(f"未找到支付记录: {payment_no}")
            return jsonify({'code': 'FAIL', 'message': '未找到支付记录'}), 404
        
        # 查询订单
        order = Order.query.get(payment.order_id)
        if not order:
            current_app.logger.error(f"未找到订单: {payment.order_id}")
            return jsonify({'code': 'FAIL', 'message': '未找到订单'}), 404
        
        # 如果支付已经处理过，直接返回成功
        if payment.status == 1 and payment.transaction_id == transaction_id:
            return jsonify({'code': 'SUCCESS', 'message': 'OK'})
        
        # 处理支付结果
        if trade_state == 'SUCCESS':
            # 开启事务
            try:
                # 更新支付记录
                payment.transaction_id = transaction_id
                payment.status = 1  # 支付成功
                payment.paid_at = datetime.now()
                
                # 更新订单状态
                order.status = 1  # 已支付
                
                # 生成签到码
                if not order.checkin_code:
                    order.checkin_code = generate_checkin_code()
                
                # 创建入场记录
                from app.models.checkin_record import CheckinRecord
                existing_record = CheckinRecord.query.filter_by(order_id=order.id).first()
                if not existing_record:
                    checkin_record = CheckinRecord.create_from_order(order)
                    db.session.add(checkin_record)
                
                # 注释掉候补用户自动转正逻辑
                # promoted_users = []
                # if order.activity_id:
                #     promoted_users = _handle_waitlist_promotion(order.activity_id)
                
                db.session.commit()
                
                current_app.logger.info(f"支付成功处理完成: {payment_no}")
                
                return jsonify({'code': 'SUCCESS', 'message': 'OK'})
                
            except Exception as e:
                db.session.rollback()
                current_app.logger.error(f"处理支付结果异常: {str(e)}")
                return jsonify({'code': 'FAIL', 'message': '处理支付结果异常'}), 500
        else:
            # 支付失败
            payment.status = 2  # 支付失败
            db.session.commit()
            
            current_app.logger.info(f"支付失败: {payment_no}, 状态: {trade_state}")
            return jsonify({'code': 'SUCCESS', 'message': 'OK'})
        
    except Exception as e:
        current_app.logger.error(f"支付回调处理异常: {str(e)}")
        return jsonify({'code': 'FAIL', 'message': '服务器错误'}), 500


@api_v1.route('/payments/query', methods=['GET'])
@swag_from(QUERY_PAYMENT_DOC)
@login_required
def query_payment():
    """查询支付状态"""
    payment_no = request.args.get('paymentNo')
    user_id = request.args.get('userId')
    
    if not payment_no:
        return jsonify({'code': 400, 'message': '缺少支付单号'}), 400
    
    # 查询支付记录
    payment = Payment.query.filter_by(payment_no=payment_no).first()
    if not payment:
        return jsonify({'code': 404, 'message': '未找到支付记录'}), 404
    
    # 查询订单
    order = Order.query.get(payment.order_id)
    if not order:
        return jsonify({'code': 404, 'message': '未找到订单'}), 404
    
    # 验证订单所属用户
    if str(order.user_id) != str(user_id):
        return jsonify({'code': 403, 'message': '无权查询该支付记录'}), 403
    
    # 如果支付状态为未支付，调用微信支付查询接口
    if payment.status == 0:
        try:
            wechat_pay = WechatPayAPI()
            result = wechat_pay.query_order(payment_no)
            
            if result:
                trade_state = result.get('trade_state')
                transaction_id = result.get('transaction_id')
                
                # 更新支付状态
                if trade_state == 'SUCCESS' and transaction_id:
                    payment.transaction_id = transaction_id
                    payment.status = 1  # 支付成功
                    payment.paid_at = datetime.now()
                    
                    # 更新订单状态
                    order.status = 1  # 已支付
                    
                    # 生成签到码
                    if not order.checkin_code:
                        order.checkin_code = generate_checkin_code()
                    
                    # 创建入场记录
                    from app.models.checkin_record import CheckinRecord
                    existing_record = CheckinRecord.query.filter_by(order_id=order.id).first()
                    if not existing_record:
                        checkin_record = CheckinRecord.create_from_order(order)
                        db.session.add(checkin_record)
                    
                    # 注释掉候补用户自动转正逻辑
                    # if order.activity_id:
                    #     _handle_waitlist_promotion(order.activity_id)
                    
                    db.session.commit()
        except Exception as e:
            current_app.logger.error(f"查询支付状态异常: {str(e)}")
    
    return jsonify({
        'code': 200,
        'message': '查询成功',
        'data': {
            'paymentId': payment.id,
            'paymentNo': payment.payment_no,
            'orderId': payment.order_id,
            'orderNo': order.order_no,
            'amount': float(payment.amount),
            'status': payment.status,
            'paidAt': payment.paid_at.strftime('%Y-%m-%d %H:%M:%S') if payment.paid_at else None,
            'orderStatus': order.status
        }
    })


# 新增手动支付回调接口，仅用于测试
@api_v1.route('/payments/manual_notify', methods=['POST'])
@swag_from(MANUAL_PAYMENT_NOTIFY_DOC)
def manual_payment_notify():
    """手动触发支付成功的回调，用于测试，通过订单号直接更新状态"""
    data = request.json
    order_no = data.get('order_no')

    if not order_no:
        return jsonify({'code': 400, 'message': '缺少 order_no 参数'}), 400

    # 1. 查询订单
    order = Order.query.filter_by(order_no=order_no).first()
    if not order:
        return jsonify({'code': 404, 'message': '未找到订单'}), 404

    # 幂等性检查：如果订单已支付，直接返回成功
    if order.status == 1:
        return jsonify({'code': 200, 'message': '该订单已支付过'})

    # 2. 查找或创建支付记录
    payment = Payment.query.filter_by(order_id=order.id).first()
    if not payment:
        from app.utils.order import generate_payment_no
        # 如果没有支付记录，为这个订单创建一个
        payment = Payment(
            order_id=order.id,
            payment_no=generate_payment_no(), 
            amount=order.amount,
            payment_method='manual',
            status=0
        )
        db.session.add(payment)

    # 3. 更新支付和订单状态
    try:
        # 更新支付记录
        payment.status = 1  # 支付成功
        if not payment.transaction_id:
            payment.transaction_id = f"manual_{order_no}"
        payment.paid_at = datetime.now(timezone(timedelta(hours=8)))
        
        # 更新订单状态
        order.status = 1  # 已支付

        # 生成签到码
        if not order.checkin_code:
            order.checkin_code = generate_checkin_code()

        # 创建入场记录
        from app.models.checkin_record import CheckinRecord
        if not CheckinRecord.query.filter_by(order_id=order.id).first():
            checkin_record = CheckinRecord.create_from_order(order)
            db.session.add(checkin_record)

        db.session.commit()
        
        current_app.logger.info(f"手动支付回调成功 (通过订单号): {order_no}")
        return jsonify({'code': 200, 'message': '手动支付回调处理成功'})

    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"手动支付回调处理异常: {e}")
        return jsonify({'code': 500, 'message': '服务器内部错误'}), 500 